<template>
  <div class="myUpload">
    <el-upload
      :ref="uploadRef"
      :file-list="childModel"
      :class="{
        'avatar-uploader': configDefault.listType === 'picture',
        btnFile: configDefault.listType === 'text' && configDefault.inputFile,
        uploadBtn:
          configDefault.listType === 'text' && !configDefault.inputFile,
      }"
      :style="configDefault.style"
      :action="configDefault.action"
      :auto-upload="configDefault.autoUpload"
      :data="configDefault.data"
      :drag="configDefault.drag"
      :headers="configDefault.headers"
      :limit="configDefault.limit"
      :list-type="configDefault.listType"
      :multiple="configDefault.multiple"
      :show-file-list="configDefault.showFileList"
      :with-credentials="configDefault.withCredentials"
      :accept="configDefault.accept"
      :disabled="configDefault.disabled"
      :name="configDefault.name"
      :before-remove="defaultBeforeRemove"
      :before-upload="defaultBeforeUpload"
      :on-change="defaultChange"
      :on-error="defaultError"
      :on-exceed="defaultExceed"
      :on-preview="defaultPreview"
      :on-progress="defaultProgress"
      :on-remove="defaultRemove"
      :on-success="defaultSuccess"
    >
      <div v-if="configDefault.listType === 'text'" class="inputFile">
        <el-input
          :placeholder="disabled ? '' : configDefault.placeholderLabel"
          v-model="fileNames"
          :disabled="configDefault.disabled"
          v-if="configDefault.inputFile"
        >
          <el-button
            size="small"
            :disabled="configDefault.disabled"
            type="primary"
            slot="append"
          >
            {{ configDefault.buttonText }}
          </el-button>
        </el-input>
        <el-tooltip
          :content="configDefault.tipMsg"
          placement="top"
          effect="light"
          :disabled="
            configDefault.disabledTip === true
              ? true
              : configDefault.disabledTip === false || configDefault.tipMsg
              ? false
              : true
          "
          v-else
        >
          <el-button
            size="small"
            type="primary"
            :disabled="configDefault.disabled"
            @click="buttonClick"
          >
            {{ configDefault.buttonText }}
          </el-button>
        </el-tooltip>
      </div>
      <div
        v-else-if="
          configDefault.listType === 'picture' ||
          configDefault.listType === 'picture-card'
        "
      >
        <img
          :src="dialogImageUrl"
          class="avatar"
          v-if="dialogImageUrl && childModel.length > 0"
        />
        <i
          class="el-icon-plus picture-icon-plus avatar-uploader-icon"
          v-if="
            !childModel ||
            childModel.length == 0 ||
            !dialogImageUrl ||
            configDefault.multiple
          "
        ></i>
      </div>
      <div class="el-upload__tip" slot="tip" v-if="configDefault.uploadTipMsg">
        {{ configDefault.uploadTipMsg }}
      </div>
    </el-upload>
  </div>
</template>
<script>
import XEUtils from "xe-utils";
export default {
  name: "myUpload",
  props: {
    //自定义ref
    uploadRef: {
      type: [Number, String],
      default() {
        return "vueUpload";
      },
    },
    model: {
      // 当前组件绑定值
      type: [String, Number, Boolean, Array],
      require: true,
    },
    modelKey: {
      //当前绑定值key，可以用于formData中获取到当前组件渲染配置items
      type: String,
      default() {
        return "";
      },
    },
    fromSource: {
      //用于formData中获取到当前组件渲染配置items
      type: [Array, String],
      default() {
        return "";
      },
    },
    which: {
      //第几组上传框
      type: [String, Number],
      default() {
        return 1;
      },
    },
    disabled: {
      // 当前组件是否禁用
      type: Boolean,
      default() {
        return false;
      },
    },
    config: {
      //私有配置数据
      type: [String, Object],
      require: true,
    },
    formConfigData: {
      //配置数据
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    return {
      childModel: [],
      fileNames: "",
      dialogImageName: "",
      dialogImageUrl: "",
      configDefault: {
        action: "", // 提交响应地址 https://jsonplaceholder.typicode.com/posts/
        props: { url: "url", name: "name" }, // 绑定值的字段别名 url为文件地址 name为文件名称
        fileSize: null, // 文件大小限制，单位为MB
        fileType: [
          // "image/gif",
          // "image/jpeg",
          // "application/pdf",
          // "image/png",
          // "text/plain",
          // "application/vnd.ms-excel",
          // "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
          // "zip",
          // "xls",
          // "xlsx",
        ], //// 文件类型限制 常用 image/gif，image/jpeg，application/pdf，image/png，text/plain,application/vnd.ms-excel(excel),"application/vnd.ms-powerpoint"(ppt) ,"application/vnd.openxmlformats-officedocument.wordprocessingml.document"（docx）
        headers: {}, // 设置请求头部
        data: {}, // 上传时附带的额外参数
        multiple: true, // 是否支持多选文件
        listType: "text", // 当前文件列表类型 text/picture/picture-card
        status: {}, // 当前文件类型为picture时判断图片上按钮显示状态 del删除按钮
        drag: false, // 是否启用拖拽
        limit: null, // 最大允许上传个数
        autoUpload: false, // 选取后自动上传
        showFileList: false, // 是否显示已上传文件列表
        withCredentials: false, // 支持发送 cookie 凭证信息
        inputFile: true,
        accept: "",
        tipMsg: "",
        uploadTipMsg: "",
        buttonText: "点击上传",
        name: "files",
        placeholderLabel: "",
      },
      isReturnUpload: true,
    };
  },
  computed: {},
  watch: {
    childModel(val, oldVal) {
      if (!XEUtils.isEqual(val, oldVal)) {
        this.$emit("update:model", val);
      }
    },
    model(val) {
      if (!XEUtils.isEqual(val, this.childModel)) {
        this.childModel = val;
      }
    },
    formConfigData: {
      handler(newVal) {
        let formConfigObj = newVal
          ? newVal[this.fromSource] || newVal[this.modelKey]
          : {};
        let publicConfigObj = newVal ? newVal["publicAttr"] : {};
        let cfg =
          this.config && XEUtils.isString(this.config)
            ? XEUtils.toStringJSON(this.config)
            : this.config || {};
        this.configDefault = XEUtils.merge(
          this.configDefault,
          publicConfigObj,
          cfg,
          formConfigObj
        );
      },
      deep: true,
      immediate: true,
    },
  },
  created() {
    this.childModel =
      Array.isArray(this.model) && this.model && this.model.length > 0
        ? this.model
        : [];
  },
  mounted() {},
  updated() {
    if (
      this.configDefault.listType === "picture" &&
      Array.isArray(this.childModel) &&
      this.childModel.length > 0
    ) {
      this.dialogImageUrl = this.childModel[0][this.configDefault.props.url];
      this.dialogImageName = this.childModel[0][this.configDefault.props.name];
    }
  },
  methods: {
    defaultPreview(file) {
      //点击文件名称时的回调
      this.$emit(
        "defaultPreviewCallback",
        this.modelKey + "_" + this.which,
        file
      );
    },
    defaultSuccess(response, file, fileList) {
      console.log("defaultSuccess");
      // 文件上传成功时的钩子
      this.$emit(
        "defaultSuccessCallback",
        this.modelKey + "_" + this.which,
        response,
        file,
        fileList
      );
    },
    defaultError(err, file, fileList) {
      console.log("defaultError");
      this.$messageWindow({
        message: err,
        type: "danger",
      });
      // 文件上传失败时的钩子
      this.$emit(
        "defaultErrorCallback",
        this.modelKey + "_" + this.which,
        file,
        fileList
      );
    },
    defaultBeforeUpload(file) { 
    // 监听上传文件之前状态
      console.log("defaultBeforeUpload");
      this.$emit(
        "defaultBeforeUploadCallback",
        this.modelKey + "_" + this.which,
        file
      );
      // 上传文件之前的钩子，参数为上传的文件，若返回 false 或者返回 Promise 且被 reject，则停止上传
      if (this.isReturnUpload) {
        return false;
      }
    },
    defaultProgress(event, file, fileList) {
      console.log("defaultProgress");
      // 文件上传时的钩子
      this.$emit(
        "defaultProgressCallback",
        this.modelKey + "_" + this.which,
        file,
        fileList
      );
    },
    defaultChange(file, fileList) {
    // 监听文件状态改变
      console.log("defaultChange");
      var FileExt = file.name ? file.name.replace(/.+\./, "") : "";
      FileExt = FileExt ? FileExt.toLowerCase() : "";
      // 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
      let fileLists =
        !this.configDefault.autoUpload && !this.configDefault.multiple
          ? [file]
          : fileList;
      const fileSize = file.size / 1024 / 1024;
      let fileName = file && file.name ? file.name : "";
      let fileNameType = fileName.substring(fileName.lastIndexOf(".") + 1);
      const fileType =
        file && file.raw && file.raw.type
          ? file.raw.type
          : file
          ? file.type || fileNameType
          : "";
      let typeFlag =
        this.configDefault.fileType && this.configDefault.fileType.length > 0
          ? false
          : true; //this.configDefault.fileType有值时，需要跟当前上传文件类型比对，默认为false
      for (let item of this.configDefault.fileType) {
        //判断当前上传文件类型是否符合要求的类型
        if (item === fileType) {
          typeFlag = true;
        }
      }
      let sizeFlag =
        this.configDefault.fileSize && fileSize > this.configDefault.fileSize
          ? false
          : true; //判断当前上传文件大小是否符合要求的大小
      if (!typeFlag) {
        const _message = this.configDefault.fileTypeName
          ? this.configDefault.fileTypeName
          : this.configDefault.fileType.join(",");
        this.$messageWindow({
          message: `上传文件类型只能是 ${_message}格式!`,
          type: "error",
        });
      }
      if (!sizeFlag) {
        this.$messageWindow({
          message: `上传文件大小不能超过 ${this.configDefault.fileSize}MB!`,
          type: "error",
        });
      }
      this.isReturnUpload = typeFlag && sizeFlag ? false : true; //typeFlag 与 sizeFlag都符合条件时不阻止上传
      if (
        this.configDefault.listType === "text" &&
        this.configDefault.inputFile
      ) {
        if (!typeFlag || !sizeFlag) {
          // 当上传不通过的时候去除fileList最后一项
          if (fileLists && fileLists.length > 0) {
            fileLists.splice(fileLists && fileLists.length - 1, 1);
          }
        }
        this.fileNames = "";
        if (fileLists && fileLists.length > 0) {
          fileLists.map((item, index) => {
            this.fileNames =
              index + 1 === fileLists.length
                ? this.fileNames + item.name
                : this.fileNames + item.name + "，";
          });
        }
      }
      console.log(44, this.fileNames, fileLists);
      this.dialogImageUrl = file[this.configDefault.url];
      this.dialogImageName = file[this.configDefault.props.name];
      this.childModel = fileLists;
      this.$emit(
        "defaultChangeCallback",
        this.modelKey + "_" + this.which,
        file,
        fileLists
      );
    },
    defaultBeforeRemove(file, fileList) {
    // 监听移除文件之前状态
      console.log("defaultBeforeRemove", file, fileList);
      this.$emit(
        "defaultBeforeRemoveCallback",
        this.modelKey + "_" + this.which,
        file,
        fileList
      );
    },
    defaultRemove(file, fileList) {
      console.log("defaultRemove", file, fileList);
      // 文件列表移除文件时的钩子
      this.$emit(
        "defaultRemoveCallback",
        this.modelKey + "_" + this.which,
        file,
        fileList
      );
      this.childModel = fileList ? fileList : [];
    },
    // 监听文件超出个数限制
    defaultExceed(files, fileList) {
      // 文件超出个数限制时的钩子
      this.$messageWindow({
        message: `当前限制选择 ${this.configDefault.limit} 个文件`,
        type: "warning",
      });
    },
    buttonClick: function () {
      //上传按钮点击事件
      this.$emit("buttonCallback", this.modelKey + "_" + this.which, {
        text: "点击上传",
        action: "upload",
        disabled: false,
      });
    },
    // httpRequest() {
    //   // 覆盖默认上传方法
    //   this.$emit("httpRequestCallback", this.modelKey + "_" + this.which);
    // },
  },
};
</script>

<style lang="less" scoped>
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 90px;
  height: 90px;
  line-height: 90px;
  text-align: center;
}
</style>
<style lang="less">
.myUpload {
  .el-upload--picture-card,
  .avatar {
    width: 90px;
    height: 90px;
    line-height: 90px;
    display: block;
  }
  .el-upload--picture {
    background-color: #fff;
    border: 1px solid #c0ccda;
    border-radius: 6px;
  }
  .el-upload--picture,
  .el-upload--text {
    cursor: default !important;
  }
  .btnFile {
    .el-upload--text {
      width: 100%;
      .inputFile {
        width: 100%;
        height: 100%;
      }
    }
  }
  .uploadBtn {
    .el-upload--text {
      width: auto !important;
    }
  }
  .el-upload {
    text-align: left;
  }
}
</style>